import { _decorator, Component, math, v3 } from 'cc'
import { bt } from '../bt/BehaviorTree'
import { Actor } from './Actor'
import { StateDefine } from './StateDefine'
import { Emit, EscapeDash, IsCooldown, IsLowHp, MoveToDest, SetMoveDest, StayIdle } from './ai/Behavior'
import { BlackboardKey } from './ai/BlackboardKey'
import { SimpleEmitter } from './projectile/SimpleEmitter'
import { Dash } from './state/Dash'
import { Die } from './state/Die'
import { Idle } from './state/Idle'
import { Run } from './state/Run'
const { ccclass, property, requireComponent } = _decorator

@ccclass('EnemyController')
@requireComponent(Actor) // 确保这个组件必须挂载在Actor上
export class EnemyController extends Component {
    actor: Actor | null = null
    ai: bt.BehaviourTree = null

    start() {
        // 初始化角色状态机
        this.actor = this.node.getComponent(Actor)
        // console.log(this.actor, 'enemy actor')
        this.createAI()
        this.initBlackboard()
        // 注册角色状态
        this.actor.stateMgr.registState(new Idle(StateDefine.Idle, this.actor))
        this.actor.stateMgr.registState(new Run(StateDefine.Run, this.actor))
        this.actor.stateMgr.registState(new Dash(StateDefine.Dash, this.actor))
        this.actor.stateMgr.registState(new Die(StateDefine.Die, this.actor))
        // 初始状态
        this.actor.stateMgr.startWith(StateDefine.Idle)

    }
    initBlackboard() {
        this.ai.setData(BlackboardKey.Escaped, false)
        this.ai.setData(BlackboardKey.Actor, this.actor)
        //this.ai.setData(BlackboardKey.AttackRange, this.attackRange);

        this.randomNextMoveDest()
    }
    createAI() {
        // console.log('createAI-------start')
        this.ai = new bt.BehaviourTree()

        // root
        let rootNode = new bt.Fallback()

        this.ai.root = rootNode

        if (1) {
            // escape
            let escapeSeq = new bt.Sequence()
            rootNode.addChild(escapeSeq)

            // has the escaped key?
            let invertHasEscapedKey = new bt.InvertResultDecorator()

            let hasEscapeKey = new bt.IsTrue()
            hasEscapeKey.key = BlackboardKey.Escaped
            invertHasEscapedKey.child = hasEscapeKey
            escapeSeq.addChild(invertHasEscapedKey)

            let lowHp = new IsLowHp()
            escapeSeq.addChild(lowHp)

            //TODO: add escape action
            let escape = new EscapeDash()
            escapeSeq.addChild(escape)
        }

        // Partrol .... move to dest position
        if (1) {
            let moveDestSeq = new bt.Sequence()

            let hasMoveDest = new bt.IsTrue()
            hasMoveDest.key = BlackboardKey.MoveDest
            moveDestSeq.addChild(hasMoveDest)

            let moveDest = new MoveToDest()
            moveDestSeq.addChild(moveDest)

            rootNode.addChild(moveDestSeq)
        }

        if (1) {
            let emitSeq = new bt.Sequence()

            let simpleEmitter = this.node.getComponentInChildren(SimpleEmitter)
            simpleEmitter.actor = this.actor
            let cooldown = new IsCooldown()
            cooldown.emitter = simpleEmitter
            emitSeq.addChild(cooldown)

            let emit = new Emit()
            emit.emitter = simpleEmitter
            emitSeq.addChild(emit)

            rootNode.addChild(emitSeq)
            // console.log(rootNode, 'enemy', simpleEmitter)
        }

        // if (0) {
        //     // chase
        //     let chaseSeq = new bt.Sequence();
        //     rootNode.addChild(chaseSeq);

        //     let hasTarget = new HasTarget();

        //     // has target ?
        //     chaseSeq.addChild(hasTarget);

        //     // is in attack range?
        //     let invInRange = new bt.InvertResultDecorator();
        //     let isInAttackRange = new IsInAttackRange();
        //     invInRange.child = isInAttackRange;
        //     chaseSeq.addChild(invInRange);

        //     // chase
        //     let chase = new Chase();
        //     chaseSeq.addChild(chase);
        // }

        // wait for nothing
        let idleSeq = new bt.Sequence()
        rootNode.addChild(idleSeq)

        idleSeq.addChild(new StayIdle())
        let wait = new bt.Wait()
        wait.elapsed = 1.0
        idleSeq.addChild(wait)
        idleSeq.addChild(new SetMoveDest())
    }


    randomNextMoveDest() {
        // 由 获取随机位置 改为找主角
        let player = this.node.parent.getChildByName('Player')
        let ramdomMoveDest = v3(math.randomRange(0, 800), math.randomRange(0, 400), 0)
        let moveDest = player?.position && this.actor.hp > 30 ? player.position : ramdomMoveDest
        this.ai.setData(BlackboardKey.MoveDest, moveDest)
        this.ai.setData(BlackboardKey.MoveDestDuration, 3.0)

    }
    update(deltaTime: number) {
        if (1) {
            this.ai.update(deltaTime)
        }
    }

}

